package com.listeningframework.boot.autoconfigure.schedule;

import java.util.Properties;

import org.quartz.impl.jdbcjobstore.JobStoreTX;
import org.quartz.impl.jdbcjobstore.StdJDBCDelegate;
import org.quartz.simpl.SimpleThreadPool;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 
 * Quartz Cluster Schedule
 *
 * @author Listening
 * @version $Id: ListeningQuartzClusterProperties.java, v 0.1 2016年6月18日 上午11:04:55 Listening Exp $
 */
@ConfigurationProperties(prefix = "listening.schedule.cluster")
public class ListeningQuartzClusterProperties {
    /**
     * Enable Cluster Schedule 
     */
    private boolean    enabled    = false;
    /**
     * Scheduler Config
     */
    private Scheduler  scheduler  = new Scheduler();
    /**
     * ThreadPool Config
     */
    private ThreadPool threadPool = new ThreadPool();
    /**
     * JobStore Config
     */
    private JobStore   jobStore   = new JobStore();

    /**
     * Getter method for property <tt>enabled</tt>.
     * 
     * @return property value of enabled
     */
    public boolean isEnabled() {
        return enabled;
    }

    /**
     * Setter method for property <tt>enabled</tt>.
     * 
     * @param enabled value to be assigned to property enabled
     */
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    /**
     * Getter method for property <tt>scheduler</tt>.
     * 
     * @return property value of scheduler
     */
    public Scheduler getScheduler() {
        return scheduler;
    }

    /**
     * Setter method for property <tt>scheduler</tt>.
     * 
     * @param scheduler value to be assigned to property scheduler
     */
    public void setScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    /**
     * Getter method for property <tt>threadPool</tt>.
     * 
     * @return property value of threadPool
     */
    public ThreadPool getThreadPool() {
        return threadPool;
    }

    /**
     * Setter method for property <tt>threadPool</tt>.
     * 
     * @param threadPool value to be assigned to property threadPool
     */
    public void setThreadPool(ThreadPool threadPool) {
        this.threadPool = threadPool;
    }

    /**
     * Getter method for property <tt>jobStore</tt>.
     * 
     * @return property value of jobStore
     */
    public JobStore getJobStore() {
        return jobStore;
    }

    /**
     * Setter method for property <tt>jobStore</tt>.
     * 
     * @param jobStore value to be assigned to property jobStore
     */
    public void setJobStore(JobStore jobStore) {
        this.jobStore = jobStore;
    }

    /**
     * 
     *  Configure Main Scheduler Properties
     *
     * @author Listening
     * @version $Id: ListeningQuartzClusterProperties.java, v 0.1 2016年6月18日 上午11:12:35 Listening Exp $
     */
    public static class Scheduler {
        private String instanceName    = "ClusteredScheduler";
        private String instanceId      = "AUTO";
        private String skipUpdateCheck = "true";

        /**
         * Getter method for property <tt>instanceName</tt>.
         * 
         * @return property value of instanceName
         */
        public String getInstanceName() {
            return instanceName;
        }

        /**
         * Setter method for property <tt>instanceName</tt>.
         * 
         * @param instanceName value to be assigned to property instanceName
         */
        public void setInstanceName(String instanceName) {
            this.instanceName = instanceName;
        }

        /**
         * Getter method for property <tt>instanceId</tt>.
         * 
         * @return property value of instanceId
         */
        public String getInstanceId() {
            return instanceId;
        }

        /**
         * Setter method for property <tt>instanceId</tt>.
         * 
         * @param instanceId value to be assigned to property instanceId
         */
        public void setInstanceId(String instanceId) {
            this.instanceId = instanceId;
        }

        /**
         * Getter method for property <tt>skipUpdateCheck</tt>.
         * 
         * @return property value of skipUpdateCheck
         */
        public String getSkipUpdateCheck() {
            return skipUpdateCheck;
        }

        /**
         * Setter method for property <tt>skipUpdateCheck</tt>.
         * 
         * @param skipUpdateCheck value to be assigned to property skipUpdateCheck
         */
        public void setSkipUpdateCheck(String skipUpdateCheck) {
            this.skipUpdateCheck = skipUpdateCheck;
        }

    }

    /**
     * 
     * Configure ThreadPool
     *
     * @author Listening
     * @version $Id: ListeningQuartzClusterProperties.java, v 0.1 2016年6月18日 上午11:12:43 Listening Exp $
     */
    public static class ThreadPool {
        private String threadPoolClass = SimpleThreadPool.class.getName();
        private String threadCount     = "5";
        private String threadPriority  = "5";

        /**
         * Getter method for property <tt>threadPoolClass</tt>.
         * 
         * @return property value of threadPoolClass
         */
        public String getThreadPoolClass() {
            return threadPoolClass;
        }

        /**
         * Setter method for property <tt>threadPoolClass</tt>.
         * 
         * @param threadPoolClass value to be assigned to property threadPoolClass
         */
        public void setThreadPoolClass(String threadPoolClass) {
            this.threadPoolClass = threadPoolClass;
        }

        /**
         * Getter method for property <tt>threadCount</tt>.
         * 
         * @return property value of threadCount
         */
        public String getThreadCount() {
            return threadCount;
        }

        /**
         * Setter method for property <tt>threadCount</tt>.
         * 
         * @param threadCount value to be assigned to property threadCount
         */
        public void setThreadCount(String threadCount) {
            this.threadCount = threadCount;
        }

        /**
         * Getter method for property <tt>threadPriority</tt>.
         * 
         * @return property value of threadPriority
         */
        public String getThreadPriority() {
            return threadPriority;
        }

        /**
         * Setter method for property <tt>threadPriority</tt>.
         * 
         * @param threadPriority value to be assigned to property threadPriority
         */
        public void setThreadPriority(String threadPriority) {
            this.threadPriority = threadPriority;
        }

    }

    /**
     * 
     * Configure JobStore
     *
     * @author Listening
     * @version $Id: ListeningQuartzClusterProperties.java, v 0.1 2016年6月18日 上午11:13:27 Listening Exp $
     */
    public static class JobStore {
        private String jobStoreClass          = JobStoreTX.class.getName();
        private String driverDelegateClass    = StdJDBCDelegate.class.getName();
        private String misfireThreshold       = "60000";
        private String useProperties          = "false";
        private String tablePrefix            = "QRTZ_";
        private String isClustered            = "true";
        private String clusterCheckinInterval = "15000";

        /**
         * Getter method for property <tt>jobStoreClass</tt>.
         * 
         * @return property value of jobStoreClass
         */
        public String getJobStoreClass() {
            return jobStoreClass;
        }

        /**
         * Setter method for property <tt>jobStoreClass</tt>.
         * 
         * @param jobStoreClass value to be assigned to property jobStoreClass
         */
        public void setJobStoreClass(String jobStoreClass) {
            this.jobStoreClass = jobStoreClass;
        }

        /**
         * Getter method for property <tt>driverDelegateClass</tt>.
         * 
         * @return property value of driverDelegateClass
         */
        public String getDriverDelegateClass() {
            return driverDelegateClass;
        }

        /**
         * Setter method for property <tt>driverDelegateClass</tt>.
         * 
         * @param driverDelegateClass value to be assigned to property driverDelegateClass
         */
        public void setDriverDelegateClass(String driverDelegateClass) {
            this.driverDelegateClass = driverDelegateClass;
        }

        /**
         * Getter method for property <tt>misfireThreshold</tt>.
         * 
         * @return property value of misfireThreshold
         */
        public String getMisfireThreshold() {
            return misfireThreshold;
        }

        /**
         * Setter method for property <tt>misfireThreshold</tt>.
         * 
         * @param misfireThreshold value to be assigned to property misfireThreshold
         */
        public void setMisfireThreshold(String misfireThreshold) {
            this.misfireThreshold = misfireThreshold;
        }

        /**
         * Getter method for property <tt>useProperties</tt>.
         * 
         * @return property value of useProperties
         */
        public String getUseProperties() {
            return useProperties;
        }

        /**
         * Setter method for property <tt>useProperties</tt>.
         * 
         * @param useProperties value to be assigned to property useProperties
         */
        public void setUseProperties(String useProperties) {
            this.useProperties = useProperties;
        }

        /**
         * Getter method for property <tt>tablePrefix</tt>.
         * 
         * @return property value of tablePrefix
         */
        public String getTablePrefix() {
            return tablePrefix;
        }

        /**
         * Setter method for property <tt>tablePrefix</tt>.
         * 
         * @param tablePrefix value to be assigned to property tablePrefix
         */
        public void setTablePrefix(String tablePrefix) {
            this.tablePrefix = tablePrefix;
        }

        /**
         * Getter method for property <tt>isClustered</tt>.
         * 
         * @return property value of isClustered
         */
        public String getIsClustered() {
            return isClustered;
        }

        /**
         * Setter method for property <tt>isClustered</tt>.
         * 
         * @param isClustered value to be assigned to property isClustered
         */
        public void setIsClustered(String isClustered) {
            this.isClustered = isClustered;
        }

        /**
         * Getter method for property <tt>clusterCheckinInterval</tt>.
         * 
         * @return property value of clusterCheckinInterval
         */
        public String getClusterCheckinInterval() {
            return clusterCheckinInterval;
        }

        /**
         * Setter method for property <tt>clusterCheckinInterval</tt>.
         * 
         * @param clusterCheckinInterval value to be assigned to property clusterCheckinInterval
         */
        public void setClusterCheckinInterval(String clusterCheckinInterval) {
            this.clusterCheckinInterval = clusterCheckinInterval;
        }

    }

    public Properties getQuartzConfig() {
        // #============================================================================
        // # Configure Main Scheduler Properties
        // #============================================================================
        // org.quartz.scheduler.instanceName: TestScheduler
        // org.quartz.scheduler.instanceId: instance_one
        // #============================================================================
        // # Configure ThreadPool
        // #============================================================================
        // org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
        // org.quartz.threadPool.threadCount: 5
        // org.quartz.threadPool.threadPriority: 5
        // #============================================================================
        // # Configure JobStore
        // #============================================================================
        // org.quartz.jobStore.misfireThreshold: 60000
        // org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
        // org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
        // org.quartz.jobStore.useProperties=false
        // org.quartz.jobStore.dataSource=myDS
        // org.quartz.jobStore.tablePrefix=QRTZ_
        // org.quartz.jobStore.isClustered=true
        // #============================================================================
        // # Configure Datasources
        // #============================================================================
        // org.quartz.dataSource.myDS.driver: org.postgresql.Driver
        // org.quartz.dataSource.myDS.URL: jdbc:postgresql://localhost:5432/quartz
        // org.quartz.dataSource.myDS.user: quartz
        // org.quartz.dataSource.myDS.password: quartz
        // org.quartz.dataSource.myDS.maxConnections: 5
        // org.quartz.dataSource.myDS.validationQuery: select 0

        Properties properties = new Properties();
        // ============================================================================
        // Configure Main Scheduler Properties
        // ============================================================================
        properties.put("org.quartz.scheduler.instanceName", scheduler.getInstanceName());
        properties.put("org.quartz.scheduler.instanceId", scheduler.getInstanceId());
        properties.put("org.quartz.scheduler.skipUpdateCheck", scheduler.getSkipUpdateCheck());
        // ============================================================================
        // Configure ThreadPool
        // ============================================================================
        properties.put("org.quartz.threadPool.class", threadPool.getThreadPoolClass());
        properties.put("org.quartz.threadPool.threadCount", threadPool.getThreadCount());
        properties.put("org.quartz.threadPool.threadPriority", threadPool.getThreadPriority());
        // ============================================================================
        // Configure JobStore
        // ============================================================================
        properties.put("org.quartz.jobStore.class", jobStore.getJobStoreClass());
        properties.put("org.quartz.jobStore.driverDelegateClass", jobStore.getDriverDelegateClass());
        properties.put("org.quartz.jobStore.misfireThreshold", jobStore.getMisfireThreshold());
        properties.put("org.quartz.jobStore.useProperties", jobStore.getUseProperties());
        properties.put("org.quartz.jobStore.tablePrefix", jobStore.getTablePrefix());
        properties.put("org.quartz.jobStore.isClustered", jobStore.getIsClustered());
        properties.put("org.quartz.jobStore.clusterCheckinInterval", jobStore.getClusterCheckinInterval());
        return properties;
    }
}
